﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ParserCore;

namespace TestParser
{
    [TestClass]
    public class StatementEqualityTest
    {
        [TestMethod]
        public void SingleExpressionStatementEquality()
        {
            var ses1 = new SingleExpressionStatement(new Identifier("dl"));
            var ses2 = new SingleExpressionStatement(new Identifier("dl"));

            Assert.AreEqual(ses1, ses2);
        }

        [TestMethod]
        public void SingleExpressionStatementInequality()
        {
            var ses1 = new SingleExpressionStatement(new Identifier("dl"));
            var ses2 = new SingleExpressionStatement(new Constant("dl"));

            Assert.AreNotEqual(ses1, ses2);
        }
        [TestMethod]
        public void AssignmentStatementEquality()
        {
            var ast1 = new AssignmentStatement(
                new Expression[] {
                    new Identifier("a"),
                    new Identifier("c")
                },
                new Constant("5")
                );
            var ast2 = new AssignmentStatement(
                new Expression[] {
                    new Identifier("a"),
                    new Identifier("c")
                },
                new Constant("5")
                );
 
            Assert.AreEqual(ast1, ast2);
        }

        [TestMethod]
        public void AssignmentStatementInequality()
        {
            var ast1 = new AssignmentStatement(
                new Expression[] {
                    new Identifier("a")
                },
                new Constant("5")
                );
            var ast2 = new AssignmentStatement(
                new Expression[] {
                    new Identifier("b")
                },
                new Constant("5")
                );
            var ast3 = new AssignmentStatement(
                new Expression[] {
                    new Identifier("a")
                },
                new Constant("0")
                );

            Assert.AreNotEqual(ast1, ast2);
            Assert.AreNotEqual(ast1, ast3);
        }

        [TestMethod]
        public void BlockStatementEquality()
        {
            var bs1 = new BlockStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var bs2 = new BlockStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );

            Assert.AreEqual(bs1, bs2);
        }
        [TestMethod]
        public void BlockStatementInequality()
        {
            var bs1 = new BlockStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var bs2 = new BlockStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var bs3 = new BlockStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("0"))
                );

            Assert.AreNotEqual(bs1, bs2);
            Assert.AreNotEqual(bs1, bs3);
        }

        [TestMethod]
        public void IfThenElseStatementEquality()
        {
            var ites1 = new IfThenElseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var ites2 = new IfThenElseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );

            Assert.AreEqual(ites1, ites2);
        }
        [TestMethod]
        public void IfThenElseStatementInequality()
        {
            var ites1 = new IfThenElseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var ites2 = new IfThenElseStatement(
                new Constant("0"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var ites3 = new IfThenElseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("0")),
                new SingleExpressionStatement(
                    new Constant("5"))
                );
            var ites4 = new IfThenElseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new SingleExpressionStatement(
                    new Constant("0"))
                );

            Assert.AreNotEqual(ites1, ites2);
            Assert.AreNotEqual(ites1, ites3);
            Assert.AreNotEqual(ites1, ites4);
        }

        [TestMethod]
        public void SwitchCaseStatementEquality()
        {
            var scs1 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5")))

                );
            var scs2 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5")))

                );

            Assert.AreEqual(scs1, scs2);
        }

        [TestMethod]
        public void SwitchCaseStatementInequality()
        {
            var scs1 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5"))));
            var scs2 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5"))),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5"))));
            var scs3 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("0"),
                        new SingleExpressionStatement(
                            new Constant("5"))));
            var scs4 = new SwitchCaseStatement(
                new Constant("0"),
                new SingleExpressionStatement(
                    new Constant("5")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5"))));
            var scs5 = new SwitchCaseStatement(
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("0")),
                new Tuple<Expression, Statement>(
                        new Constant("5"),
                        new SingleExpressionStatement(
                            new Constant("5"))));

            Assert.AreNotEqual(scs1, scs2);
            Assert.AreNotEqual(scs1, scs3);
            Assert.AreNotEqual(scs1, scs4);
            Assert.AreNotEqual(scs1, scs5);
        }

        [TestMethod]
        public void ForStatementEquality()
        {
            var fs1 = new ForStatement(
                new Identifier("a"),
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")));

            var fs2 = new ForStatement(
                 new Identifier("a"),
                 new Constant("5"),
                 new SingleExpressionStatement(
                     new Constant("5")));

            Assert.AreEqual(fs1, fs2);

        }

        [TestMethod]
        public void ForStatementInequality()
        {
            var fs1 = new ForStatement(
                new Identifier("a"),
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("5")));

            var fs2 = new ForStatement(
                 new Identifier("b"),
                 new Constant("5"),
                 new SingleExpressionStatement(
                     new Constant("5")));

            var fs3 = new ForStatement(
                new Identifier("a"),
                new Constant("0"),
                new SingleExpressionStatement(
                    new Constant("5")));

            var fs4 = new ForStatement(
                new Identifier("a"),
                new Constant("5"),
                new SingleExpressionStatement(
                    new Constant("0")));

            Assert.AreNotEqual(fs1, fs2);
            Assert.AreNotEqual(fs1, fs3);
            Assert.AreNotEqual(fs1, fs4);

        }

        [TestMethod]
        public void WhileStatementEquality()
        {
            var ws1 = new WhileStatement(
                    new Constant("5"),
                    new SingleExpressionStatement(
                        new Constant("5")));
            var ws2 = new WhileStatement(
                    new Constant("5"),
                    new SingleExpressionStatement(
                        new Constant("5")));

            Assert.AreEqual(ws1, ws2);
        }

        [TestMethod]
        public void WhileStatementInequality()
        {
            var ws1 = new WhileStatement(
                    new Constant("5"),
                    new SingleExpressionStatement(
                        new Constant("5")));
            var ws2 = new WhileStatement(
                    new Constant("0"),
                    new SingleExpressionStatement(
                        new Constant("5")));
            var ws3 = new WhileStatement(
                     new Constant("5"),
                     new SingleExpressionStatement(
                         new Constant("0")));

            Assert.AreNotEqual(ws1, ws2);
            Assert.AreNotEqual(ws1, ws3);
        }

        [TestMethod]
        public void BreakStatementEquality()
        {
            var bs1 = new BreakStatement();
            var bs2 = new BreakStatement();

            Assert.AreEqual(bs1, bs2);
        }

        [TestMethod]
        public void BreakStatementInequality()
        {
            var bs1 = new BreakStatement();
            var bs2 = new SingleExpressionStatement(
                    new Constant("5"));
            BreakStatement bs3 = null;

            Assert.AreNotEqual(bs1, bs2);
            Assert.AreNotEqual(bs1, bs3);
        }

        [TestMethod]
        public void ContinueStatementEquality()
        {
            var cs1 = new ContinueStatement();
            var cs2 = new ContinueStatement();

            Assert.AreEqual(cs1, cs2);
        }

        [TestMethod]
        public void ContinueStatementInequality()
        {
            var cs1 = new ContinueStatement();
            var cs2 = new BreakStatement();
            ContinueStatement cs3 = null;

            Assert.AreNotEqual(cs1, cs2);
            Assert.AreNotEqual(cs1, cs3);
        }

        [TestMethod]
        public void TryCatchStatementEquality()
        {
            var tcs1 = new TryCatchStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new Identifier("a"),
                new SingleExpressionStatement(
                    new Constant("5")));

            var tcs2 = new TryCatchStatement(
                 new SingleExpressionStatement(
                     new Constant("5")),
                 new Identifier("a"),
                 new SingleExpressionStatement(
                     new Constant("5")));

            Assert.AreEqual(tcs1, tcs2);
        }

        [TestMethod]
        public void TryCatchStatementInequality()
        {
            var tcs1 = new TryCatchStatement(
                new SingleExpressionStatement(
                    new Constant("5")),
                new Identifier("a"),
                new SingleExpressionStatement(
                    new Constant("5")));

            var tcs2 = new TryCatchStatement(
                 new SingleExpressionStatement(
                     new Constant("0")),
                 new Identifier("a"),
                 new SingleExpressionStatement(
                     new Constant("5")));

            var tcs3 = new TryCatchStatement(
                  new SingleExpressionStatement(
                      new Constant("5")),
                  new Identifier("b"),
                  new SingleExpressionStatement(
                      new Constant("5")));

            var tcs4 = new TryCatchStatement(
                  new SingleExpressionStatement(
                      new Constant("5")),
                  new Identifier("a"),
                  new SingleExpressionStatement(
                      new Constant("0")));

            Assert.AreNotEqual(tcs1, tcs2);
            Assert.AreNotEqual(tcs1, tcs3);
            Assert.AreNotEqual(tcs1, tcs4);
        }

        [TestMethod]
        public void ReturnStatementEqualityTest()
        {
            var st1 = new ReturnStatement();
            var st2 = new ReturnStatement();
            Assert.AreEqual(st1, st2);
        }

        [TestMethod]
        public void ReturnStatementInequalityTest()
        {
            var st = new ReturnStatement();
            var st1 = new SingleExpressionStatement(new Constant("a"));
            ReturnStatement st2 = null;
            Assert.AreNotEqual(st, st1);
            Assert.AreNotEqual(st, st2);
        }

        [TestMethod]
        public void FunctionDefinitionStatementEqualityTest()
        {
            var st1 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement( new Identifier("c"))
                );
            var st2 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            Assert.AreEqual(st1, st2);
        }

        [TestMethod]
        public void FunctionDefinitionStatementInequalityTest()
        {
            var st = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st1 = new FunctionDefinitionStatement(
                new Identifier("x"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st2 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3"),
                    new Identifier("a4")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st3 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("x2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st4 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3"),
                    new Identifier("b4")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st5 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("x2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("c"))
                );
            var st6 = new FunctionDefinitionStatement(
                new Identifier("a"),
                new Identifier[] { 
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")},
                new Identifier[] { 
                    new Identifier("b1"),
                    new Identifier("b2"),
                    new Identifier("b3")},
                new SingleExpressionStatement(new Identifier("x"))
                );
            Assert.AreNotEqual(st, st1);
            Assert.AreNotEqual(st, st2);
            Assert.AreNotEqual(st, st3);
            Assert.AreNotEqual(st, st4);
            Assert.AreNotEqual(st, st5);
            Assert.AreNotEqual(st, st6);
        }

        [TestMethod]
        public void GlobalDeclarationStatementEqualityTest()
        {
            var st1 = new GlobalDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            var st2 = new GlobalDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            Assert.AreEqual(st1, st2);
        }

        [TestMethod]
        public void GlobalDeclarationStatementInequalityTest()
        {
            var st = new GlobalDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            var st1 = new GlobalDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3"),
                    new Identifier("a4")}
                    );
            var st2 = new GlobalDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("x2"),
                    new Identifier("a3")}
                    );

            Assert.AreNotEqual(st, st1);
            Assert.AreNotEqual(st, st2);

        }
        [TestMethod]
        public void PersistentDeclarationStatementEqualityTest()
        {
            var st1 = new PersistentDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            var st2 = new PersistentDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            Assert.AreEqual(st1, st2);
        }

        [TestMethod]
        public void PersistentDeclarationStatementInequalityTest()
        {
            var st = new PersistentDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3")}
                    );
            var st1 = new PersistentDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("a2"),
                    new Identifier("a3"),
                    new Identifier("a4")}
                    );
            var st2 = new PersistentDeclarationStatement(
                new Identifier[]{
                    new Identifier("a1"),
                    new Identifier("x2"),
                    new Identifier("a3")}
                    );

            Assert.AreNotEqual(st, st1);
            Assert.AreNotEqual(st, st2);

        }


    }
}
